<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <svg id="svg" width="600" height="600"></svg>
    <script>
        var arr = [2, 8, 7, 4, 1, 5];
        var svg = document.querySelector("svg");
        var width = svg.getAttribute("width");
        var height = svg.getAttribute("height");
        var margin_vertical = 20, margin_level = 20;
        var max_height = getMaxHeight(arr);
        var animation_flag = false;
        var deley_count = 0;
        var deley_space = 1000;
        var show_count = 0;

        function getMaxHeight(arr) {
            let max = arr[0];
            for (let i = 1; i < arr.length; i++) {
                if (max < arr[i]) {
                    max = arr[i];
                }
                return max;
            }
        }
        function getHeight(i) {
            return (i / max) * (height - margin_vertical) * 0.8;
        }
        max = getMaxHeight(arr)
        function showArr(arr, m, n) { // j i
            console.log(arr, n, m)
            var rectStr = "", lineStr = "", textStr = "" ;
            let rect_width = (width - 2 * margin_vertical) / arr.length * 0.6;
            let rect_height = 0;
            let space_width = rect_width * 2 / 3;
            let cx = 0;
            let cy = 0;

            let fontSize = rect_width / 2 ? 20 : rect_width / 2;
            for (var i = 0; i < arr.length; i++) {
                let color = '#5CACEE'
                console.log("第" + i + '次', "n" + n + "m" + m)
                if (i === n) {
                    color = "black"
                }
                if (i == m) {
                    color = "red"
                }
                rect_height = getHeight(arr[i]);
                cy = height - rect_height - 2 * margin_vertical - 1;
                cx = (rect_width + space_width) * i + margin_level;
                rectStr += '<rect x="' + cx + '" y="' + cy + '" width="' + rect_width + '" height="' + rect_height + '" fill="' + color + '"/>';
                textStr += '<text x="' + (cx + rect_width / 2) + '"y="' + (cy - 3) + '"fill="#171717"style="text-anchor:middle;font-size:' + fontSize + 'pt">' + arr[i] + '</text>'
                textStr += '<text x="' + (cx + rect_width / 2) + '" y="' + (height - 10) + '"fill="#171717"style="text-anchor:middle;font-size:' + fontSize + 'pt">' + (i + 1) + '</text>'
            }
            lineStr = '<line x1="0" x2="0" y1 ="0" y2="' + (height - 2 * margin_vertical) + '"style="stroke:#666;stroke-width:4"/>'
                + '<line y1="' + (height - 2 * margin_vertical) + '" y2="' + (height - 2 * margin_vertical) + '" x1="0" x2="' + width + '"style="stroke:#666;stroke-width:4"/>'
            svg.innerHTML = rectStr + lineStr + textStr;
        }
        var showSort = function (arr, m, n) {
            var array = [];
            for (let i = 0; i < arr.length; i++) {
                array[i] = arr[i];
            }
            var callback = function (array, m, n) {
                animation_flag = true;
                showArr(array, m, n);
                deley_count++;
                if (deley_count >= show_count) {
                    setTimeout(function () {
                        showArr(array);
                        animation_flag = false;//动画执行完毕
                        console.log("排序完成");
                        show_count = 0;
                        deley_count = 0;
                    }, deley_space);
                }
            }
            setTimeout(callback, deley_space * show_count++, array, m, n);
        }

        function showAnimation(arr, m, n) {
            var array = [];
            for (let i = 0; i < arr.length; i++) {
                array[i] = arr[i];
            }
            let callback = function () {
                showArr(array, m, n);
                deley_count++;
                if (deley_count >= show_count) {
                    showArr(arr)
                    deley_count = 0;
                    show_count = 0;
                    console.log("排序完成")
                }
            }
            setTimeout(callback, deley_space * show_count++)
        }

        function shellSort(arr) {


            let gap = Math.floor(arr.length / 2);
            while (gap > 0) {
                for (let i = gap; i < arr.length; i++) {
                    for (var j = i - gap; j >= 0; j -= gap) {
                        // (function (a, b, c) {
                        //     var array = [];
                        //     for (let i = 0; i < arr.length; i++) {
                        //         array[i] = a[i];
                        //     }
                        //     setTimeout(() => {
                        //         showArr(array,b,c)
                        //     }, deley_space*show_count++);
                        // })(arr, j, j + gap)

                        // (function (arr, j, s) {
                        //     var array = [];
                        //     for (let i = 0; i < arr.length; i++) {
                        //         array[i] = arr[i];
                        //     }
                        //     setTimeout(function (m) {
                        //         console.log(m)
                        //         showArr(array, j, s)
                        //     }, deley_space * show_count++, array)
                        // })(arr, j, j + gap)

                        // (function(arr,m,n){
                        //     let array = []
                        //     for(let i=0;i<arr.length;i++){
                        //         array[i] = arr[i];
                        //     }
                        //     var  callback = function(){
                        //         deley_count++;
                        //         showArr(array,m,n)
                        //         if(deley_count>=show_count){
                        //         showArr(array);
                        //         show_count = 0;
                        //         deley_count = 0;
                        //         console.log("排序完成")
                        //     }
                        //     }
                        //     setTimeout(callback,deley_space*show_count++)
                        // })(arr,j,j+gap)

                        // (function (arr, m, n) {
                        //     let array = [];
                        //     for (let i = 0; i < arr.length; i++) {
                        //         array[i] = arr[i];
                        //     }
                        //     let callback = function () {
                        //         deley_count++;
                        //         showArr(array, m, n)
                        //         if (deley_count >= show_count) {
                        //             showArr(arr)
                        //             deley_count = 0;
                        //             show_count = 0;
                        //             console.log("排序完成")
                        //         }
                        //     }
                        //     setTimeout(callback, deley_space * show_count++)
                        // })(arr, j, j + gap)

                        // 注释的这一段为直接用闭包函数写的动画效果

                        showAnimation(arr, j, j + gap)

                        if (arr[j + gap] > arr[j]) {
                            break;
                        }
                        if (arr[j + gap] < arr[j]) {
                            let temp = arr[j + gap]
                            arr[j + gap] = arr[j];
                            arr[j] = temp;
                            (function (arr, m, n) {
                                let array = []
                                for (let i = 0; i < arr.length; i++) {
                                    array[i] = arr[i];
                                }
                                var callback = function () {
                                    deley_count++;
                                    showArr(array, m, n)
                                    if (deley_count >= show_count) {
                                        showArr(array);
                                        show_count = 0;
                                        deley_count = 0;
                                        console.log("排序完成")
                                    }
                                }
                                setTimeout(callback, deley_space * show_count++)
                            })(arr, j, j + gap)

                        }
                    }
                }
                gap = Math.floor(gap / 2);
            }

        }


        shellSort(arr)

    </script>
</body>

</html>